热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

出库管理|零件设计中的状态模式学习心得与应用分析

篇首语:本文由编程笔记#小编为大家整理,主要介绍了设计模式学习笔记之状态模式相关的知识,希望对你有一定的参考价值。 什么是状态模式呢? 允许一个对象在其内部状态改变时改变它的行为。对象看

篇首语:本文由编程笔记#小编为大家整理,主要介绍了设计模式学习笔记之状态模式相关的知识,希望对你有一定的参考价值。


什么是状态模式呢?

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。。。是不是听起来显示在内部进行零件调换的感觉,其实是有点类似这种想法的,只不过调换的零件就是封装好的状态。

让我们来举个例子




在我还上学的时候,寝室楼下有一台这样的自动贩售机,专门卖饮料。每天晚上寝室关门之后口渴了,在这里面买点饮料喝喝还是很方便的。

下面用程序来模拟一下这个售货机:


可乐售货机类:


/**
*
* 可乐自动贩售机类
* @author birdlove1987
*
*/
public class VendingMachine

//售空
final static int SoldOutState = 0;

//在售
final static int OnReadyState = 1;

//有币
final static int HasCoin = 2;

//出货
final static int SoldState = 3;
//售货机状态
private int state = SoldOutState;

//机内可乐数量
private int count = 0;
//构造函数,初始化自动贩售机
public VendingMachine(int count)

this.count = count;
if (count > 0)
state = OnReadyState;


//向贩售机投币函数
public void insertCoin()

switch (state)

case SoldOutState:
System.out.println("请不要投币了,售货机里已经没有可乐了!");
break;
case OnReadyState:
state = HasCoin;
System.out.println("投币成功,请按出货按钮!");
break;
case HasCoin:
System.out.println("售货机里以及有硬币了,请勿重复投币!");
break;
case SoldState:
System.out.println("正在出货请勿投币!");
break;


//贩售机退币函数
public void returnCoin()

switch (state)

case SoldOutState:
System.out.println("您还没有投币!");
break;
case OnReadyState:
System.out.println("您还没有投币!");
break;
case HasCoin:
System.out.println("请在退币口收好您的硬币");
state = OnReadyState;
break;
case SoldState:
System.out.println("可乐已售出,不能退币");
break;


//按出可乐按钮函数
public void pressButton()

switch (state)

case SoldOutState:
System.out.println("对不起,可乐已售空!");
break;
case OnReadyState:
System.out.println("请您先投币!");
break;
case HasCoin:
System.out.println("请稍等,出可乐中!");
state = SoldState;
appearCola();
break;
case SoldState:
System.out.println("可乐已出,如想再次购买请再次投币!");
break;


//售货机出可乐函数
private void appearCola()

count = count - 1;
System.out.println("出货口,滚出了一瓶可乐!");
if (count > 0)

state = OnReadyState;

else

System.out.println("对不起,可乐已经售空了,请勿在投币!");
state = SoldOutState;


//打印目前售货机的状态
public void printState()

switch (state)

case SoldOutState:
System.out.println("=========售空=========");
break;
case OnReadyState:
System.out.println("=========售卖中=========");
break;
case HasCoin:
System.out.println("=========已投币=========");
break;
case SoldState:
System.out.println("=========出货中=========");
break;





写个测试类来测试一下

测试类


/**
* 测试类
* @author birdlove1987
*
*/
public class MainTest
public static void main(String[] args)

//创建售货机实例,并且只放入一瓶可乐
VendingMachine mVendingMachine=new VendingMachine(1);


//打印售货机状态
mVendingMachine.printState();

//投币
mVendingMachine.insertCoin();

//打印售货机状态
mVendingMachine.printState();

//按出货按钮
mVendingMachine.pressButton();


//打印售货机状态
mVendingMachine.printState();

//投币
mVendingMachine.insertCoin();

//打印售货机状态
mVendingMachine.printState();

//按出货按钮
mVendingMachine.pressButton();

//打印售货机状态
mVendingMachine.printState();






嗯!模拟成功了!好像感觉还不错呢!不过买了一段时间,你可能发现,如果不搞一些促销活动,更本就搞不过那些有促销的商家!




所以自动售货机也要搞一个“再来一瓶”的活动啊!

但是!!!如果现在直接在自动售货机的类上去直接修改,就违背了软件设计里的“开-闭原则”了,破坏了我们已经闭合的类。所以现在看来,这种设计并不好。。

下面就轮到状态设计模式登场啦,我们从新构建类,这次以状态为类,来构建。

首先定义一下状态接口


/***
* 状态接口
* @author birdlove1987
*
*/
public interface State

//投币函数
public void insertCoin();

//退币函数
public void returnCoin();

//按出可乐按钮函数
public void pressButton();

//出可乐函数
public void appearCola();

//打印状态函数
public void printState();




再来定义状态类


/***
* 在售状态类
* @author birdlove1987
*
*/
public class OnReadyState implements State

//贩售机引用
private VendingMachine mVendingMachine;

//构造函数初始化
public OnReadyState(VendingMachine mVendingMachine)

this.mVendingMachine=mVendingMachine;


@Override
public void insertCoin()

// TODO Auto-generated method stub
System.out.println("投币成功,请按出货按钮!");
mVendingMachine.setState(mVendingMachine.mHasCoin);

@Override
public void returnCoin()

// TODO Auto-generated method stub
System.out.println("您还没有投币!");


@Override
public void pressButton()

// TODO Auto-generated method stub
System.out.println("请您先投币!");


@Override
public void appearCola()

// TODO Auto-generated method stub

@Override
public void printState()

// TODO Auto-generated method stub
System.out.println("=========售卖中=========");

/***
* 售空状态类
* @author birdlove1987
*
*/
public class SoldOutState implements State
private VendingMachine mVendingMachine;
public SoldOutState(VendingMachine mCandyMachine)

this.mVendingMachine=mVendingMachine;

@Override
public void insertCoin()

// TODO Auto-generated method stub
System.out.println("请不要投币了,售货机里已经没有可乐了!");


@Override
public void returnCoin()

// TODO Auto-generated method stub
System.out
.println("您还没有投币!");

@Override
public void pressButton()

// TODO Auto-generated method stub
System.out.println("对不起,可乐已售空!");


@Override
public void appearCola()

// TODO Auto-generated method stub

@Override
public void printState()
// TODO Auto-generated method stub
System.out.println("=========售空=========");



/***
* 已投币状态类
* @author birdlove1987
*
*/
public class HasCoin implements State

private VendingMachine mVendingMachine;
public HasCoin(VendingMachine mVendingMachine)

this.mVendingMachine = mVendingMachine;

@Override
public void insertCoin()

// TODO Auto-generated method stub
System.out.println("售货机里以及有硬币了,请勿重复投币!");

@Override
public void returnCoin()

// TODO Auto-generated method stub
System.out.println("请在退币口收好您的硬币");
mVendingMachine.setState(mVendingMachine.mOnReadyState);

@Override
public void pressButton()

// TODO Auto-generated method stub
System.out.println("请稍等,出可乐中!");

//创建随机中奖概率
Random anotherOne = new Random();

//20%的机会再来一瓶
int luck = anotherOne.nextInt(5);
if(luck==0)

mVendingMachine.setState(mVendingMachine.mOneMoreCola);
else

mVendingMachine.setState(mVendingMachine.mSoldState);


@Override
public void appearCola()


@Override
public void printState()

// TODO Auto-generated method stub
System.out.println("=========已投币=========");

/**
* 出可乐状态类
* @author birdlove1987
*
*/
public class SoldState implements State
private VendingMachine mVendingMachine;
public SoldState(VendingMachine mVendingMachine)

this.mVendingMachine=mVendingMachine;

@Override
public void insertCoin()

// TODO Auto-generated method stub
System.out.println("正在出货请勿投币!");

@Override
public void returnCoin()

// TODO Auto-generated method stub
System.out.println("可乐已售出,不能退币");


@Override
public void pressButton()

// TODO Auto-generated method stub
System.out
.println("可乐已出,如想再次购买请再次投币!");

@Override
public void appearCola()

// TODO Auto-generated method stub

mVendingMachine.appearCola();
if (mVendingMachine.getCount() > 0)

mVendingMachine.setState(mVendingMachine.mOnReadyState);

else

System.out.println("对不起,可乐已经售空了,请勿在投币!");
mVendingMachine.setState(mVendingMachine.mSoldOutState);



@Override
public void printState()

// TODO Auto-generated method stub
System.out.println("=========出货中=========");


/***
* 再来一瓶类
* @author birdlove1987
*
*/
public class OneMoreCola implements State
private VendingMachine mVendingMachine;
public OneMoreCola(VendingMachine mVendingMachine)

this.mVendingMachine = mVendingMachine;

@Override
public void insertCoin()

// TODO Auto-generated method stub
System.out.println("正在出货请勿投币!");

@Override
public void returnCoin()

// TODO Auto-generated method stub
System.out.println("可乐已售出,不能退币");

@Override
public void pressButton()

// TODO Auto-generated method stub
System.out.println("请稍等,出可乐中!");

@Override
public void appearCola()

// TODO Auto-generated method stub

mVendingMachine.appearCola();
if (mVendingMachine.getCount() == 0)

mVendingMachine.setState(mVendingMachine.mSoldOutState);

else

System.out.println("恭喜你获得了再来一瓶,马上为您再出一瓶可乐");
mVendingMachine.appearCola();
if (mVendingMachine.getCount() > 0)

mVendingMachine.setState(mVendingMachine.mOnReadyState);

else

System.out.println("对不起,可乐已经售空了,请勿在投币!");
mVendingMachine.setState(mVendingMachine.mSoldOutState);



@Override
public void printState()

// TODO Auto-generated method stub
System.out.println("=========再来一瓶=========");





构建自动贩售机类


/**
* 自动售货机类
* @author birdlove1987
*
*/
public class VendingMachine
//状态类引用
State mSoldOutState;
State mOnReadyState;
State mHasCoin;
State mSoldState;
State mOneMoreCola;

//目前状态
private State state;

//可乐计数器
private int count = 0;
//构造函数
public VendingMachine(int count)

this.count = count;
mSoldOutState = new SoldOutState(this);
mOnReadyState = new OnReadyState(this);
mHasCoin = new HasCoin(this);
mSoldState = new SoldState(this);
mOneMoreCola = new OneMoreCola(this);
if (count > 0)

state = mOnReadyState;

else

state = mSoldOutState;


//设置状态函数
public void setState(State state)

this.state = state;

//投币函数
public void insertCoin()

state.insertCoin();


//退币函数
public void returnCoin()

state.returnCoin();


//按出可乐按钮函数
public void pressButton()

state.pressButton();
state.appearCola();

//出可乐函数
void appearCola()

// TODO Auto-generated method stub
if (count > 0)

count = count - 1;
System.out.println("出货口,滚出了一瓶可乐!");


//可乐计数函数
public int getCount()

return count;


//打印状态函数
public void printState()

state.printState();




最后写一个测试类测试一下


/**
* 测试类
* @author birdlove1987
*
*/
public class MainTest
public static void main(String[] args)


//实例化自动贩售机对象
VendingMachine mVendingMachine = new VendingMachine(10);

//打印状态
mVendingMachine.printState();
//投币
mVendingMachine.insertCoin();

//打印状态
mVendingMachine.printState();
//按出可乐按钮
mVendingMachine.pressButton();
//打印状态
mVendingMachine.printState();
//投币
mVendingMachine.insertCoin();

//打印状态
mVendingMachine.printState();
//按出可乐按钮
mVendingMachine.pressButton();
//打印状态
mVendingMachine.printState();









卧槽!一次都没中奖,什么鬼!!!不行,买买买!!!




中了一次。。。好吧,我来作弊一下。。调到100%




哈哈哈!


状态模式的优点
    1.状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
    2.将与状态有关的行为封装到一个类中,方便地增加新的状态,只需改变对象状态即可改变对象的行为。 
    3.提供代码复用性,降低了程序的某些耦合性。   
     
状态模式的缺点
    1.有时候状态类会很多,而且逻辑复杂。

状态模式适用场景
    1、对象的行为依赖于它的状态,并且其行为依据它的状态改变而改变。 
    2、代码中包含大量与对象状态有关的条件语句









推荐阅读
  • JavaScript 基础语法指南
    本文详细介绍了 JavaScript 的基础语法,包括变量、数据类型、运算符、语句和函数等内容,旨在为初学者提供全面的入门指导。 ... [详细]
  • 异常要理解Java异常处理是如何工作的,需要掌握一下三种异常类型:检查性异常:最具代表性的检查性异常是用户错误或问题引起的异常ÿ ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 不确定性|放入_华为机试题 HJ9提取不重复的整数
    不确定性|放入_华为机试题 HJ9提取不重复的整数 ... [详细]
  • C语言基础入门:7个经典小程序助你快速掌握编程技巧
    本文精选了7个经典的C语言小程序,旨在帮助初学者快速掌握编程基础。通过这些程序的实践,你将更深入地理解C语言的核心概念和语法结构。 ... [详细]
  • 本题探讨了在一个有向图中,如何根据特定规则将城市划分为若干个区域,使得每个区域内的城市之间能够相互到达,并且划分的区域数量最少。题目提供了时间限制和内存限制,要求在给定的城市和道路信息下,计算出最少需要划分的区域数量。 ... [详细]
  • 本文详细介绍了 org.apache.commons.io.IOCase 类中的 checkCompareTo() 方法,通过多个代码示例展示其在不同场景下的使用方法。 ... [详细]
  • 对象自省自省在计算机编程领域里,是指在运行时判断一个对象的类型和能力。dir能够返回一个列表,列举了一个对象所拥有的属性和方法。my_list[ ... [详细]
  • 本问题探讨了在特定条件下排列儿童队伍的方法数量。题目要求计算满足条件的队伍排列总数,并使用递推算法和大数处理技术来解决这一问题。 ... [详细]
  • 本文介绍如何使用 Android 的 Canvas 和 View 组件创建一个简单的绘图板应用程序,支持触摸绘画和保存图片功能。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • 深入解析SpringMVC核心组件:DispatcherServlet的工作原理
    本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
author-avatar
Lai-flip_179
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有